﻿Imports System.Runtime.CompilerServices
Imports System.IO
Imports System.IO.Packaging
Imports System.Windows.Xps.Packaging
Imports System.Windows.Xps.Serialization
Imports Microsoft.Win32

Public Module FlowDocumentExtensions

    <Extension()>
    Public Function Clone(ByVal doc As FlowDocument) As FlowDocument
        Dim clonedoc As New FlowDocument
        'clonedoc.PageWidth = doc.PageWidth
        'clonedoc.PageHeight = doc.PageHeight
        'clonedoc.PagePadding = doc.PagePadding
        'clonedoc.ColumnGap = doc.ColumnGap
        'clonedoc.ColumnWidth = doc.ColumnWidth
        'clonedoc.FontFamily = doc.FontFamily
        'clonedoc.FontWeight = doc.FontWeight
        'clonedoc.FontSize = doc.FontSize
        'clonedoc.LineHeight = doc.LineHeight
        'clonedoc.LineStackingStrategy = doc.LineStackingStrategy

        Dim sourceRange As New TextRange(doc.ContentStart, doc.ContentEnd)
        Dim destRange As New TextRange(clonedoc.ContentStart, clonedoc.ContentEnd)

        Dim ms As New MemoryStream
        sourceRange.Save(ms, DataFormats.Xaml, preserveTextElements:=False)
        destRange.Load(ms, DataFormats.Xaml)

        Return clonedoc
    End Function

    ''' <summary>
    ''' extension method to convert flowdocument to xps and send job to printer dialog
    ''' </summary>
    ''' <param name="doc"></param>
    ''' <remarks></remarks>
    <Extension()>
    Public Sub Print(ByVal doc As FlowDocument)
        Dim clonedoc As New FlowDocument

        Dim sourceRange As New TextRange(doc.ContentStart, doc.ContentEnd)
        Dim destRange As New TextRange(clonedoc.ContentStart, clonedoc.ContentEnd)

        Dim ms As New MemoryStream
        sourceRange.Save(ms, DataFormats.Xaml, preserveTextElements:=False)
        destRange.Load(ms, DataFormats.Xaml)

        Dim tempPath As String = Path.Combine(Path.GetTempPath, String.Format("{0}.xps", Guid.NewGuid.ToString()))
        Using pkg As Package = Package.Open(tempPath, FileMode.Create)
            Dim pkgUri As New Uri("pack://temp.xps")
            PackageStore.AddPackage(pkgUri, pkg)


            Using printDoc As New XpsDocument(pkg, CompressionOption.Fast, pkgUri.OriginalString)
                Dim rsm As New XpsSerializationManager(New XpsPackagingPolicy(printDoc), False)

                'Dim hDoc As New FlowDocument
                'Dim header As New 
                'hDoc.Blocks.Add(header)
                'Dim hPaginator As DocumentPaginator = DirectCast(hDoc, IDocumentPaginatorSource).DocumentPaginator
                ''todo - move this inside the custom paginator
                'hPaginator.PageSize = New Size(768 - 48 * 2, 1056 - 48 * 2)

                'Dim hPage As DocumentPage = hPaginator.GetPage(0)

                Dim pp As New PrintDialog
                clonedoc.ColumnWidth = pp.PrintableAreaWidth
                clonedoc.PagePadding = New Thickness(48)

                Dim paginator As DocumentPaginator = DirectCast(clonedoc, IDocumentPaginatorSource).DocumentPaginator
                With paginator
                    .PageSize = New Size(pp.PrintableAreaWidth, pp.PrintableAreaHeight)
                End With
                Dim customPaginator As New CustomDocumentPaginator(paginator,
                                                                    New Size(pp.PrintableAreaHeight, pp.PrintableAreaWidth),
                                                                   New Size(clonedoc.PagePadding.Left, clonedoc.PagePadding.Right),
                                                                    0, 0)

                'customPaginator.TemplatePage = hPage

                'customPaginator.HeaderVisual = headerBorder

                rsm.SaveAsXaml(customPaginator)

                Dim printPaginator As DocumentPaginator = printDoc.GetFixedDocumentSequence.DocumentPaginator
                With pp
                    .PageRangeSelection = PageRangeSelection.AllPages
                    .UserPageRangeEnabled = True
                    .PrintTicket.PageOrientation = Printing.PageOrientation.Landscape
                End With
                printPaginator.PageSize = New Size(pp.PrintableAreaWidth, pp.PrintableAreaHeight)

                If pp.ShowDialog Then
                    pp.PrintDocument(printPaginator, "Print document")
                End If
            End Using
            'to launch xps viewer (needs to be installed and associated with .xps files)
            'Process.Start(tempPath)
            PackageStore.RemovePackage(pkgUri)
        End Using

    End Sub

End Module
